<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" >

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/turbolinks/5.2.0/turbolinks.js" integrity="sha256-iM4Yzi/zLj/IshPWMC1IluRxTtRjMqjPGd97TZ9yYpU=" crossorigin="anonymous"></script>
  <link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css?family=Cousine|Inconsolata" rel="stylesheet">
  <link rel="shortcut icon" type="image/png" href="/favicon.png">

  <link rel="stylesheet" href="/css/style.css">
  <link rel="stylesheet" href="/css/css/fontawesome-all.min.css">
  <link rel="stylesheet" href="/css/css/work-sans-v7.css">
  <script src="/js/main.js"></script>

  <!-- Begin Jekyll SEO tag v2.6.1 -->
<title>PY: Grant Posting Permission | Hive Developer</title>
<meta name="generator" content="Jekyll v4.0.0" />
<meta property="og:title" content="PY: Grant Posting Permission" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="How to give another user posting permission on your account using Python." />
<meta property="og:description" content="How to give another user posting permission on your account using Python." />
<link rel="canonical" href="grant_posting_permission.html" />
<meta property="og:url" content="grant_posting_permission.html" />
<meta property="og:site_name" content="Hive Developer" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2020-08-26T11:52:22-07:00" />
<script type="application/ld+json">
{"description":"How to give another user posting permission on your account using Python.","mainEntityOfPage":{"@type":"WebPage","@id":"grant_posting_permission.html"},"@type":"BlogPosting","url":"grant_posting_permission.html","headline":"PY: Grant Posting Permission","dateModified":"2020-08-26T11:52:22-07:00","datePublished":"2020-08-26T11:52:22-07:00","@context":"https://schema.org"}</script>
<!-- End Jekyll SEO tag -->


  
</head>
<body>
<header>
  <h1>
    <button type="button" class="open-nav" id="open-nav"></button>
    <a href="/"  class="logo-link"><img src="/images/logotype_black.svg" height="40" alt="Hive Developer logo"></a>
  </h1>

  
  <form action="/search/" method="get">
    <input type="text" name="q" id="search-input" placeholder="Search">
    <input type="submit" value="Search" style="display: none;">
  </form>
  

  <div id="sidebar" class="sidebar">
	
	
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/">
		<h6 class="ctrl-nav-section title">Introduction</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/#introduction-welcome">Welcome to Hive</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/quickstart/">
		<h6 class="ctrl-nav-section title">Quickstart</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/quickstart/#quickstart-choose-library">Choose Library</a></li>
						
					
						
						<li><a href="/quickstart/#quickstart-hive-full-nodes">Hive Nodes</a></li>
						
					
						
						<li><a href="/quickstart/#quickstart-testnet">Hive Testnet</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/tutorials/">
		<h6 class="ctrl-nav-section title">Tutorials</h6>
		<ul class="cont-nav-section content">
			
				
					
						<li><a href="/tutorials/#tutorials-javascript">Javascript</a></li>
					
				
					
						<li><a href="/tutorials/#tutorials-python">Python</a></li>
					
				
					
						<li><a href="/tutorials/#tutorials-ruby">Ruby</a></li>
					
				
					
						<li><a href="/tutorials/#tutorials-recipes">Recipes</a></li>
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/services/">
		<h6 class="ctrl-nav-section title">Services</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/services/#services-hive-blog">hive.blog</a></li>
						
					
						
						<li><a href="/services/#services-hivesigner">HiveSigner</a></li>
						
					
						
						<li><a href="/services/#services-jussi">Jussi</a></li>
						
					
						
						<li><a href="/services/#services-imagehoster">ImageHoster</a></li>
						
					
						
						<li><a href="/services/#services-dhf">DHF</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/apidefinitions/">
		<h6 class="ctrl-nav-section title">Appbase API</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/apidefinitions/#apidefinitions-condenser-api">Condenser Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-bridge">Bridge</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-account-by-key-api">Account By Key Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-account-history-api">Account History Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-block-api">Block Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-database-api">Database Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-debug-node-api">Debug Node Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-follow-api">Follow Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-jsonrpc">Jsonrpc</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-market-history-api">Market History Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-network-broadcast-api">Network Broadcast Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-rc-api">Rc Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-reputation-api">Reputation Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-rewards-api">Rewards Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-tags-api">Tags Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-transaction-status-api">Transaction Status Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-witness-api">Witness Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-broadcast-ops">Broadcast Ops</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-broadcast-ops-communities">Broadcast Ops Communities</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/resources/">
		<h6 class="ctrl-nav-section title">Resources</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/resources/#resources-overview">Overview</a></li>
						
					
						
						<li><a href="/resources/#resources-client-libs">Client Libraries</a></li>
						
					
						
						<li><a href="/resources/#resources-bluepaper">Bluepaper</a></li>
						
					
						
						<li><a href="/resources/#resources-whitepaper">Whitepaper</a></li>
						
					
						
						<li><a href="/resources/#resources-tools">Tools</a></li>
						
					
						
						<li><a href="/resources/#resources-hivesigner-libs">Hivesigner Libs</a></li>
						
					
						
						<li><a href="/resources/#resources-hive-keychain">Hive Keychain</a></li>
						
					
						
						<li><a href="/resources/#resources-developeradvocate">Community & Help</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/glossary/">
		<h6 class="ctrl-nav-section title">Glossary</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/glossary/#glossary-chain-basics">Chain Basics</a></li>
						
					
						
					
						
						<li><a href="/glossary/#glossary-governance">Governance</a></li>
						
					
						
						<li><a href="/glossary/#glossary-transactions">Transactions</a></li>
						
					
						
						<li><a href="/glossary/#glossary-api">API</a></li>
						
					
						
						<li><a href="/glossary/#glossary-market">Market</a></li>
						
					
				
			
		</ul>
	</section>
	
</div>



  <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
</header>
<div class="main" id="top">
  <div class="hero">
    <h1 class="hero__h1">Hive Developer Portal </h1>
    <img class="hero__img" src="/images/honey-comb-92.png" style="position: relative; top: 10px;" />
  </div>
  <section id="tutorials-python-grant-posting-permission" class="row tutorials-python-grant-posting-permission">
	<h3>
		<a id="tutorials-python-grant-posting-permission">
			PY: Grant Posting Permission
			
		</a>
	</h3>
	
		<span class="description"><p>How to give another user posting permission on your account using Python.</p>
</span>
	

	<p><span class="fa-pull-left top-of-tutorial-repo-link"><span class="first-word">Full</span>, runnable src of <a href="https://gitlab.syncad.com/hive/devportal/-/tree/master/tutorials/python/tutorials/30_grant_posting_permission">Grant Posting Permission</a> can be downloaded as part of: <a href="https://gitlab.syncad.com/hive/devportal/-/tree/master/tutorials/python">tutorials/python</a>.</span>
<br /></p>

<p>In this tutorial we show you how to check if someone has posting permission for an account on the <strong>Steem</strong> blockchain and how to grant or revoke that permission using the <code class="highlighter-rouge">commit</code> class found within the <a href="https://github.com/steemit/steem-python">steem-python</a> library.</p>

<p>Providing another user posting permission for your account can be used to allow multiple users to submit posts on a single steemit community. @Utopian-Io is an example of such a community. There are also applications that allows you to schedule posts by automatically publishing on your behalf.</p>

<h2 id="intro">Intro</h2>

<p>The Steem python library has a built-in function to transmit transactions to the blockchain. We are using the <code class="highlighter-rouge">allow</code> and <code class="highlighter-rouge">disallow</code> methods found within the <code class="highlighter-rouge">commit</code> class in the library. Before we grant or revoke permission, we use the <code class="highlighter-rouge">get_account</code> function to check whether the requested user already has that permission or not. This is not strictly necessary but adds to the useability of the process. The <code class="highlighter-rouge">allow</code> method has 5 parameters:</p>

<ol>
  <li><em>foreign</em> - The foreign account that will obtain access</li>
  <li><em>weight</em> - This is an optional parameter defining the weight to use. If not defined, the threshold value will be used. If the weight is smaller than the threshold, additional signatures will be required.</li>
  <li><em>permission</em> - The actual permission to modify. This value must be either “posting”, “active” or “owner”</li>
  <li><em>account</em> - The account to allow access to</li>
  <li><em>threshold</em> - The threshold that needs to be reached by signatures to be able to interact</li>
</ol>

<p>The <code class="highlighter-rouge">disallow</code> method uses the same parameters except for <code class="highlighter-rouge">weight</code> which is not required.</p>

<p>There is currently a bug with the <code class="highlighter-rouge">disallow</code> method when using it on the testnet that we normally connect to. Due to that bug, we are using the production server for this tutorial. Special care should be taken when creating transactions as everything we do will affect <code class="highlighter-rouge">real</code> accounts.</p>

<h2 id="steps">Steps</h2>

<ol>
  <li><a href="#setup"><strong>App setup</strong></a> - Library install and import. Input user info and connection to production</li>
  <li><a href="#username"><strong>Username validation</strong></a> - Check validity of user and foreign account</li>
  <li><a href="#status"><strong>Check permission status</strong></a> - Check current permission status of foreign account</li>
  <li><a href="#commit"><strong>Commit to blockchain</strong></a> - Commit transaction to blockchain</li>
</ol>

<h4 id="1-app-setup-and-connection-">1. App setup and connection <a name="setup"></a></h4>

<p>In this tutorial we use 2 packages:</p>

<ul>
  <li><code class="highlighter-rouge">steem</code> - steem-python library and interaction with Blockchain</li>
  <li><code class="highlighter-rouge">pick</code> - helps select the query type interactively</li>
</ul>

<p>We import the libraries for the application.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">steembase</span>
<span class="kn">import</span> <span class="nn">steem</span>
<span class="kn">from</span> <span class="nn">pick</span> <span class="kn">import</span> <span class="n">pick</span>
</code></pre></div></div>

<p>We require the <code class="highlighter-rouge">private active key</code> of the user in order for the <code class="highlighter-rouge">allow</code> or <code class="highlighter-rouge">disallow</code> to be committed to the blockchain. The values are supplied via the terminal/console before we initialise the steem class with the supplied private key included.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#capture user information
</span><span class="n">username</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s">'Enter username: '</span><span class="p">)</span>
<span class="n">wif</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s">'Enter private ACTIVE key: '</span><span class="p">)</span>

<span class="c1">#connect to production server with active key
</span><span class="n">client</span> <span class="o">=</span> <span class="n">steem</span><span class="o">.</span><span class="n">Steem</span><span class="p">(</span><span class="n">keys</span><span class="o">=</span><span class="p">[</span><span class="n">wif</span><span class="p">])</span>
</code></pre></div></div>

<h4 id="2-username-validation-">2. Username validation <a name="username"></a></h4>

<p>Both the main account granting the permission and the account that permission is being granted to are first checked to make certain that they do in fact exist. We do this with the <code class="highlighter-rouge">get_account</code> function.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#check valid user
</span><span class="n">userinfo</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get_account</span><span class="p">(</span><span class="n">username</span><span class="p">)</span>
<span class="k">if</span><span class="p">(</span><span class="n">userinfo</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">)</span> <span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'Oops. Looks like user '</span> <span class="o">+</span> <span class="n">username</span> <span class="o">+</span> <span class="s">' doesn</span><span class="se">\'</span><span class="s">t exist on this chain!'</span><span class="p">)</span>
    <span class="nb">exit</span><span class="p">()</span>

<span class="c1">#get account to authorise and check if valid
</span><span class="n">foreign_acc</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s">'Please enter the account name for POSTING authorisation: '</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">foreign_acc</span> <span class="o">==</span> <span class="n">username</span><span class="p">)</span> <span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'Cannot allow or disallow posting permission to your own account'</span><span class="p">)</span>
    <span class="nb">exit</span><span class="p">()</span>
<span class="n">foreign_userinfo</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get_account</span><span class="p">(</span><span class="n">foreign_acc</span><span class="p">)</span>
<span class="k">if</span><span class="p">(</span><span class="n">foreign_userinfo</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">)</span> <span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'Oops. Looks like user '</span> <span class="o">+</span> <span class="n">foreign_acc</span> <span class="o">+</span> <span class="s">' doesn</span><span class="se">\'</span><span class="s">t exist on this chain!'</span><span class="p">)</span>
    <span class="nb">exit</span><span class="p">()</span>
</code></pre></div></div>

<h4 id="3-check-permission-status-">3. Check permission status <a name="status"></a></h4>

<p>In order to determine which function to execute (<code class="highlighter-rouge">allow</code> or <code class="highlighter-rouge">disallow</code>) we first need to check whether the requested user already has permission or not. We do this with the same variable created in the previous step. The <code class="highlighter-rouge">get_account</code> function has a value - <code class="highlighter-rouge">posting</code> - that contains an array of all the usernames that has been granted posting permission for the account being queried. We use this check to limit the options of the user as you cannot grant permission to a user that already has permission or revoke permission of a user that does not yet have permission. The information is displayed on the options list.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#check if foreign_account already has posting auth
</span><span class="n">_data</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">title</span> <span class="o">=</span> <span class="s">''</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">userinfo</span><span class="p">[</span><span class="s">'posting'</span><span class="p">][</span><span class="s">'account_auths'</span><span class="p">]))</span> <span class="p">:</span>
    <span class="n">_data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">userinfo</span><span class="p">[</span><span class="s">'posting'</span><span class="p">][</span><span class="s">'account_auths'</span><span class="p">][</span><span class="n">i</span><span class="p">])</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">_data</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">foreign_acc</span><span class="p">)</span> <span class="p">:</span>
        <span class="n">title</span> <span class="o">=</span> <span class="p">(</span><span class="n">foreign_acc</span> <span class="o">+</span> <span class="s">' already has posting permission. Please choose option from below list'</span><span class="p">)</span>
        <span class="n">options</span> <span class="o">=</span> <span class="p">[</span><span class="s">'DISALLOW'</span><span class="p">,</span> <span class="s">'CANCEL'</span><span class="p">]</span>

<span class="k">if</span> <span class="p">(</span><span class="n">title</span> <span class="o">==</span> <span class="s">''</span><span class="p">)</span> <span class="p">:</span>
    <span class="n">title</span> <span class="o">=</span> <span class="p">(</span><span class="n">foreign_acc</span> <span class="o">+</span> <span class="s">' does not yet posting permission. Please choose option from below list'</span><span class="p">)</span>
    <span class="n">options</span> <span class="o">=</span> <span class="p">[</span><span class="s">'ALLOW'</span><span class="p">,</span> <span class="s">'CANCEL'</span><span class="p">]</span>
</code></pre></div></div>

<h4 id="4-commit-to-blockchain-">4. Commit to blockchain <a name="commit"></a></h4>

<p>Based on the check in the previous step, the user is given the option to <code class="highlighter-rouge">allow</code>, <code class="highlighter-rouge">disallow</code> or <code class="highlighter-rouge">cancel</code> the operation completely. All the required parameters have already been assigned via console/terminal input and based on the choice of the user the relevant function can be executed. A confirmation of the succesfully executed action is displayed on the UI.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">option</span><span class="p">,</span> <span class="n">index</span> <span class="o">=</span> <span class="n">pick</span><span class="p">(</span><span class="n">options</span><span class="p">,</span> <span class="n">title</span><span class="p">)</span>

<span class="k">if</span> <span class="p">(</span><span class="n">option</span> <span class="o">==</span> <span class="s">'CANCEL'</span><span class="p">)</span> <span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'operation cancelled'</span><span class="p">)</span>
    <span class="nb">exit</span><span class="p">()</span>

<span class="k">if</span> <span class="p">(</span><span class="n">option</span> <span class="o">==</span> <span class="s">'ALLOW'</span><span class="p">)</span> <span class="p">:</span>
    <span class="c1">#allow(foreign, weight=None, permission='posting', account=None, threshold=None)
</span>    <span class="n">client</span><span class="o">.</span><span class="n">allow</span><span class="p">(</span><span class="n">foreign</span><span class="o">=</span><span class="n">foreign_acc</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">permission</span><span class="o">=</span><span class="s">'posting'</span><span class="p">,</span> <span class="n">account</span><span class="o">=</span><span class="n">username</span><span class="p">,</span> <span class="n">threshold</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="n">foreign_acc</span> <span class="o">+</span> <span class="s">' has been granted posting permission'</span><span class="p">)</span>
<span class="k">else</span> <span class="p">:</span>
    <span class="c1">#disallow(foreign, permission='posting', account=None, threshold=None)
</span>    <span class="n">client</span><span class="o">.</span><span class="n">disallow</span><span class="p">(</span><span class="n">foreign</span><span class="o">=</span><span class="n">foreign_acc</span><span class="p">,</span> <span class="n">permission</span><span class="o">=</span><span class="s">'posting'</span><span class="p">,</span> <span class="n">account</span><span class="o">=</span><span class="n">username</span><span class="p">,</span> <span class="n">threshold</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'posting permission for '</span> <span class="o">+</span> <span class="n">foreign_acc</span> <span class="o">+</span> <span class="s">' has been removed'</span><span class="p">)</span>
</code></pre></div></div>

<p>And that’s it!</p>

<h3 id="to-run-the-tutorial">To Run the tutorial</h3>

<ol>
  <li><a href="getting_started.html">review dev requirements</a></li>
  <li><code class="highlighter-rouge">git clone https://gitlab.syncad.com/hive/devportal.git</code></li>
  <li><code class="highlighter-rouge">cd devportal/tutorials/python/30_grant_posting_permission</code></li>
  <li><code class="highlighter-rouge">pip install -r requirements.txt</code></li>
  <li><code class="highlighter-rouge">python index.py</code></li>
  <li>After a few moments, you should see a prompt for input in terminal screen.</li>
</ol>

<hr />

</section>

</div>
<div class="footer">
  <a href="#">Back to top</a>
</div>
<script>
    document.getElementById("open-nav").addEventListener("click", function () {
        document.body.classList.toggle("nav-open");
    });
</script>
</body>
</html>


<script src="/js/adjust.js"></script>

